#include "../include/processes.h"
#include <stdlib.h>
#include <string.h>

void writer(const void *data, size_t size,const char* Path)
{
#ifdef _WIN32
    HANDLE hFile = CreateFile(
        Path,
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE)
    {
        fprintf(stderr, "CreateFile failed (%lu)\n", GetLastError());
        return;
    }

    // 设置文件大小为实际数据大小
    if (SetFilePointer(hFile, size - 1, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
        !SetEndOfFile(hFile))
    {
        fprintf(stderr, "Set file size failed (%lu)\n", GetLastError());
        CloseHandle(hFile);
        return;
    }

    HANDLE hMap = CreateFileMapping(
        hFile,
        NULL,
        PAGE_READWRITE,
        0,
        size,
        NULL);

    if (!hMap)
    {
        fprintf(stderr, "CreateFileMapping failed (%lu)\n", GetLastError());
        CloseHandle(hFile);
        return;
    }

    char *pData = (char *)MapViewOfFile(
        hMap,
        FILE_MAP_ALL_ACCESS,
        0, 0, size);
#else
    int fd = shm_open(Path, O_CREAT | O_RDWR | O_TRUNC, 0666);
    if (fd == -1)
    {
        perror("shm_open failed");
        return;
    }

    if (ftruncate(fd, size) == -1)
    {
        perror("ftruncate failed");
        close(fd);
        return;
    }

    char *pData = mmap(NULL, size,
                       PROT_READ | PROT_WRITE,
                       MAP_SHARED,
                       fd, 0);
#endif

    if (!pData)
    {
#ifdef _WIN32
        fprintf(stderr, "MapViewOfFile failed (%lu)\n", GetLastError());
        CloseHandle(hMap);
        CloseHandle(hFile);
#else
        perror("mmap failed");
        close(fd);
#endif
        return;
    }

    // 使用memcpy复制任意二进制数据
    memcpy(pData, data, size);

    // 清理资源
#ifdef _WIN32
    UnmapViewOfFile(pData);
    CloseHandle(hMap);
    CloseHandle(hFile);
#else
    munmap(pData, size);
    close(fd);
#endif
}

void* reader(size_t* out_size,const char*Path)
{
#ifdef _WIN32
    HANDLE hFile = CreateFile(
        Path,
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
        fprintf(stderr, "CreateFile failed (%lu)\n", GetLastError());
        return NULL;
    }

    DWORD size = GetFileSize(hFile, NULL);
    HANDLE hMap = CreateFileMapping(
        hFile,
        NULL,
        PAGE_READONLY,
        0,
        size,
        NULL);

    if (!hMap) {
        fprintf(stderr, "CreateFileMapping failed (%lu)\n", GetLastError());
        CloseHandle(hFile);
        return NULL;
    }

    char* pData = (char*)MapViewOfFile(
        hMap,
        FILE_MAP_READ,
        0, 0, size);
#else
    int fd = shm_open(Path, O_RDONLY, 0666);
    if (fd == -1) {
        perror("shm_open failed");
        return NULL;
    }

    off_t size = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    char* pData = mmap(NULL, size,
                      PROT_READ,
                      MAP_SHARED,
                      fd, 0);
#endif

    if (!pData) {
#ifdef _WIN32
        fprintf(stderr, "MapViewOfFile failed (%lu)\n", GetLastError());
        CloseHandle(hMap);
        CloseHandle(hFile);
#else
        perror("mmap failed");
        close(fd);
#endif
        return NULL;
    }

    // 将数据拷贝到堆内存中
    void* data_copy = malloc(size);
    if (data_copy) {
        memcpy(data_copy, pData, size);
        *out_size = size;
    } else {
        *out_size = 0;
    }

    // 清理资源
#ifdef _WIN32
    UnmapViewOfFile(pData);
    CloseHandle(hMap);
    CloseHandle(hFile);
#else
    munmap(pData, size);
    close(fd);
    shm_unlink(SHM_NAME); // 移除共享内存对象
#endif

    return data_copy;
}